package cn.turboinfo.fuyang.api.domain.admin.usecase.company;

import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyAuditRecordService;
import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyAuthLabelService;
import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyService;
import cn.turboinfo.fuyang.api.domain.common.service.file.FileAttachmentService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.entity.common.enumeration.audit.AuditStatus;
import cn.turboinfo.fuyang.api.entity.common.enumeration.company.CompanyStatus;
import cn.turboinfo.fuyang.api.entity.common.exception.company.HousekeepingCompanyException;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.*;
import com.google.common.collect.Lists;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

/**
 * @author gadzs
 * @description 家政企业创建usecase
 * @date 2023/1/29 16:26
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class HousekeepingCompanyCreateUseCase extends AbstractUseCase<HousekeepingCompanyCreateUseCase.InputData, HousekeepingCompanyCreateUseCase.OutputData> {
    private final HousekeepingCompanyService housekeepingCompanyService;
    private final HousekeepingCompanyAuthLabelService housekeepingCompanyAuthLabelService;
    private final FileAttachmentService fileAttachmentService;
    private final HousekeepingCompanyAuditRecordService housekeepingCompanyAuditRecordService;

    @Override
    protected OutputData doAction(InputData inputData) {
        Optional<HousekeepingCompany> housekeepingCompanyOptional1 = housekeepingCompanyService.findByUscc(inputData.getUscc());
        if (housekeepingCompanyOptional1.isPresent() && housekeepingCompanyOptional1.get().getStatus() != CompanyStatus.NOTPASS) {
            throw new HousekeepingCompanyException("社会信用代码已存在");
        }
        Optional<HousekeepingCompany> housekeepingCompanyOptional2 = housekeepingCompanyService.findByContactNumber(inputData.getContactNumber());
        if (housekeepingCompanyOptional2.isPresent() && housekeepingCompanyOptional2.get().getStatus() != CompanyStatus.NOTPASS) {
            throw new HousekeepingCompanyException("手机号码已存在，请更换");
        }
        inputData.setCompanyStatus(CompanyStatus.REGISTER);

        if (housekeepingCompanyOptional1.isPresent()) {
            HousekeepingCompany company = housekeepingCompanyOptional1.get();

            // 删除原有附件
            fileAttachmentService.findByRefId(company.getId())
                    .forEach(fileAttachment -> fileAttachmentService.deleteById(fileAttachment.getId()));

            HousekeepingCompanyUpdater.Builder builder = HousekeepingCompanyUpdater.builder(company.getId());
            QBeanUpdaterHelper.copyPropertiesToUpdateBuilder(builder, HousekeepingCompanyUpdater.class, inputData);
            if (inputData.getAuthLabelIdList() != null && !inputData.getAuthLabelIdList().isEmpty()) {
                val housekeepingCompanyAuthLabels = housekeepingCompanyAuthLabelService.findByIdCollection(inputData.getAuthLabelIdList());
                housekeepingCompanyAuthLabels.forEach(housekeepingCompanyAuthLabel -> {
                    housekeepingCompanyAuthLabel.setDescription(null);
                });
                builder.withAuthLabelList(housekeepingCompanyAuthLabels)
                        .withAuthLabelWeight((long) housekeepingCompanyAuthLabels.stream().mapToInt(HousekeepingCompanyAuthLabel::getWeight).sum());
            }
            HousekeepingCompany housekeepingCompany = housekeepingCompanyService.update(builder
                    .withAppId(StringUtils.EMPTY)
                    .withAppSecret(StringUtils.EMPTY)
                    .withStatus(CompanyStatus.REGISTER)
                    .build());

            List<Long> fileIdList = Lists.newArrayList(housekeepingCompany.getBusinessLicenseFile(), housekeepingCompany.getLegalPersonIdCardFile(), housekeepingCompany.getBankAccountCertificateFile());
            fileAttachmentService.updateRefId(fileIdList, housekeepingCompany.getId());

            {
                HousekeepingCompanyAuditRecordCreator housekeepingCompanyAuditRecord = HousekeepingCompanyAuditRecordCreator.builder()
                        .withCompanyId(housekeepingCompany.getId())
                        .withAuditStatus(AuditStatus.AGAIN)
                        .withUserId(0L)
                        .withUserName(StringUtils.EMPTY)
                        .withRemark("企业重新提交审核")
                        .build();
                housekeepingCompanyAuditRecordService.save(housekeepingCompanyAuditRecord);
            }

            return OutputData.builder()
                    .housekeepingCompany(housekeepingCompany)
                    .build();
        } else {
            HousekeepingCompanyCreator.Builder builder = HousekeepingCompanyCreator.builder();
            QBeanCreatorHelper.copyPropertiesToCreatorBuilder(builder, HousekeepingCompanyCreator.class, inputData);
            if (inputData.getAuthLabelIdList() != null && !inputData.getAuthLabelIdList().isEmpty()) {
                val housekeepingCompanyAuthLabels = housekeepingCompanyAuthLabelService.findByIdCollection(inputData.getAuthLabelIdList());
                housekeepingCompanyAuthLabels.forEach(housekeepingCompanyAuthLabel -> {
                    housekeepingCompanyAuthLabel.setDescription(null);
                });
                builder.withAuthLabelList(housekeepingCompanyAuthLabels);
                builder.withAuthLabelWeight((long) housekeepingCompanyAuthLabels.stream().mapToInt(HousekeepingCompanyAuthLabel::getWeight).sum());
            }
            HousekeepingCompany housekeepingCompany = housekeepingCompanyService.save(builder
                    .withAppId(StringUtils.EMPTY)
                    .withAppSecret(StringUtils.EMPTY)
                    .build());

            List<Long> fileIdList = Lists.newArrayList(housekeepingCompany.getBusinessLicenseFile(), housekeepingCompany.getLegalPersonIdCardFile(), housekeepingCompany.getBankAccountCertificateFile());
            fileAttachmentService.updateRefId(fileIdList, housekeepingCompany.getId());

            {
                HousekeepingCompanyAuditRecordCreator housekeepingCompanyAuditRecord = HousekeepingCompanyAuditRecordCreator.builder()
                        .withCompanyId(housekeepingCompany.getId())
                        .withAuditStatus(AuditStatus.INIT)
                        .withUserId(0L)
                        .withUserName(StringUtils.EMPTY)
                        .withRemark("企业注册")
                        .build();
                housekeepingCompanyAuditRecordService.save(housekeepingCompanyAuditRecord);
            }

            return OutputData.builder()
                    .housekeepingCompany(housekeepingCompany)
                    .build();
        }
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        @NotBlank(
                message = "统一社会信用代码不能为空"
        )
        private String uscc;

        @NotBlank(
                message = "企业名称"
        )
        private String name;

        @NotNull(
                message = "成立日期不能为空"
        )
        private LocalDate establishmentDate;

        @NotNull(
                message = "省id不能为空"
        )
        private Long provinceCode;

        @NotNull(
                message = "市id不能为空"
        )
        private Long cityCode;

        @NotNull(
                message = "区id不能为空"
        )
        private Long areaCode;

        @NotBlank(
                message = "注册地址不能为空"
        )
        private String registeredAddress;

        private BigDecimal registeredCapital;

        @NotBlank(
                message = "公司类型不能为空"
        )
        private String companyType;

        @NotBlank(
                message = "法人不能为空"
        )
        private String legalPerson;

        @NotBlank(
                message = "法人身份证不能为空"
        )
        private String legalPersonIdCard;

        @NotBlank(
                message = "联系人不能为空"
        )
        private String contactPerson;

        @NotBlank(
                message = "联系电话不能为空"
        )
        private String contactNumber;


        private String email;

        @NotBlank(
                message = "员工人数不能为空"
        )
        private String employeesNumber;

        @NotNull(
                message = "营业执照不能为空"
        )
        private Long businessLicenseFile;

        @NotNull(
                message = "法定代表人身份证不能为空"
        )
        private Long legalPersonIdCardFile;

        @NotNull(
                message = "银行开户证明不能为空"
        )
        private Long bankAccountCertificateFile;

        @NotNull(
                message = "家政公司类型不能为空"
        )
        private String houseKeepingType;

        @NotNull(
                message = "公司短名不能为空"
        )
        private String shortName;

        /**
         * 企业状态
         */
        private CompanyStatus companyStatus;

        /**
         * 认证id列表
         */
        private List<Long> authLabelIdList;

    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {
        private HousekeepingCompany housekeepingCompany;
    }

}
